package com.carbeauty.entity;

import com.carbeauty.common.entity.BaseEntity;
import com.fasterxml.jackson.annotation.JsonFormat;
import jakarta.persistence.*;
import jakarta.validation.constraints.DecimalMin;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;

import java.math.BigDecimal;
import java.time.LocalDate;

/**
 * 材料实体类
 * 
 * 材料管理功能:
 * - 材料基本信息
 * - 库存管理
 * - 价格管理
 * - 供应商管理
 * - 有效期管理
 * 
 * @author CarBeauty Team
 */
@Entity
@Table(name = "cb_material")
public class Material extends BaseEntity {
    
    /**
     * 材料名称
     */
    @NotBlank(message = "材料名称不能为空")
    @Size(max = 100, message = "材料名称长度不能超过100个字符")
    @Column(name = "name", nullable = false, length = 100)
    private String name;
    
    /**
     * 材料编码 - 唯一标识
     */
    @Size(max = 50, message = "材料编码长度不能超过50个字符")
    @Column(name = "code", unique = true, length = 50)
    private String code;
    
    /**
     * 材料分类
     */
    @NotBlank(message = "材料分类不能为空")
    @Size(max = 50, message = "材料分类长度不能超过50个字符")
    @Column(name = "category", nullable = false, length = 50)
    private String category;
    
    /**
     * 材料规格
     */
    @Size(max = 100, message = "材料规格长度不能超过100个字符")
    @Column(name = "specification", length = 100)
    private String specification;
    
    /**
     * 计量单位
     */
    @NotBlank(message = "计量单位不能为空")
    @Size(max = 20, message = "计量单位长度不能超过20个字符")
    @Column(name = "unit", nullable = false, length = 20)
    private String unit;
    
    /**
     * 当前库存数量
     */
    @NotNull(message = "库存数量不能为空")
    @DecimalMin(value = "0", message = "库存数量不能为负数")
    @Column(name = "stock", nullable = false, precision = 10, scale = 2)
    private BigDecimal stock = BigDecimal.ZERO;
    
    /**
     * 最小库存预警值
     */
    @DecimalMin(value = "0", message = "最小库存不能为负数")
    @Column(name = "min_stock", precision = 10, scale = 2)
    private BigDecimal minStock = BigDecimal.ZERO;
    
    /**
     * 最大库存值
     */
    @DecimalMin(value = "0", message = "最大库存不能为负数")
    @Column(name = "max_stock", precision = 10, scale = 2)
    private BigDecimal maxStock;
    
    /**
     * 采购价格
     */
    @DecimalMin(value = "0", message = "采购价格不能为负数")
    @Column(name = "purchase_price", precision = 10, scale = 2)
    private BigDecimal purchasePrice = BigDecimal.ZERO;
    
    /**
     * 销售价格
     */
    @DecimalMin(value = "0", message = "销售价格不能为负数")
    @Column(name = "sale_price", precision = 10, scale = 2)
    private BigDecimal salePrice = BigDecimal.ZERO;
    
    /**
     * 供应商名称
     */
    @Size(max = 100, message = "供应商名称长度不能超过100个字符")
    @Column(name = "supplier", length = 100)
    private String supplier;
    
    /**
     * 供应商联系方式
     */
    @Size(max = 100, message = "供应商联系方式长度不能超过100个字符")
    @Column(name = "supplier_contact", length = 100)
    private String supplierContact;
    
    /**
     * 生产日期
     */
    @Column(name = "production_date")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private LocalDate productionDate;
    
    /**
     * 有效期至
     */
    @Column(name = "expiry_date")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private LocalDate expiryDate;
    
    /**
     * 存放位置
     */
    @Size(max = 100, message = "存放位置长度不能超过100个字符")
    @Column(name = "storage_location", length = 100)
    private String storageLocation;
    
    /**
     * 材料描述
     */
    @Size(max = 500, message = "材料描述长度不能超过500个字符")
    @Column(name = "description", length = 500)
    private String description;
    
    /**
     * 材料图片URL
     */
    @Size(max = 200, message = "图片URL长度不能超过200个字符")
    @Column(name = "image_url", length = 200)
    private String imageUrl;
    
    // ==================== 构造方法 ====================
    
    public Material() {
        super();
    }
    
    public Material(String name, String category, String unit) {
        super();
        this.name = name;
        this.category = category;
        this.unit = unit;
        this.generateCode();
    }
    
    // ==================== Getter/Setter ====================
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public String getCode() {
        return code;
    }
    
    public void setCode(String code) {
        this.code = code;
    }
    
    public String getCategory() {
        return category;
    }
    
    public void setCategory(String category) {
        this.category = category;
    }
    
    public String getSpecification() {
        return specification;
    }
    
    public void setSpecification(String specification) {
        this.specification = specification;
    }
    
    public String getUnit() {
        return unit;
    }
    
    public void setUnit(String unit) {
        this.unit = unit;
    }
    
    public BigDecimal getStock() {
        return stock;
    }
    
    public void setStock(BigDecimal stock) {
        this.stock = stock;
    }
    
    public BigDecimal getMinStock() {
        return minStock;
    }
    
    public void setMinStock(BigDecimal minStock) {
        this.minStock = minStock;
    }
    
    public BigDecimal getMaxStock() {
        return maxStock;
    }
    
    public void setMaxStock(BigDecimal maxStock) {
        this.maxStock = maxStock;
    }
    
    public BigDecimal getPurchasePrice() {
        return purchasePrice;
    }
    
    public void setPurchasePrice(BigDecimal purchasePrice) {
        this.purchasePrice = purchasePrice;
    }
    
    public BigDecimal getSalePrice() {
        return salePrice;
    }
    
    public void setSalePrice(BigDecimal salePrice) {
        this.salePrice = salePrice;
    }
    
    public String getSupplier() {
        return supplier;
    }
    
    public void setSupplier(String supplier) {
        this.supplier = supplier;
    }
    
    public String getSupplierContact() {
        return supplierContact;
    }
    
    public void setSupplierContact(String supplierContact) {
        this.supplierContact = supplierContact;
    }
    
    public LocalDate getProductionDate() {
        return productionDate;
    }
    
    public void setProductionDate(LocalDate productionDate) {
        this.productionDate = productionDate;
    }
    
    public LocalDate getExpiryDate() {
        return expiryDate;
    }
    
    public void setExpiryDate(LocalDate expiryDate) {
        this.expiryDate = expiryDate;
    }
    
    public String getStorageLocation() {
        return storageLocation;
    }
    
    public void setStorageLocation(String storageLocation) {
        this.storageLocation = storageLocation;
    }
    
    public String getDescription() {
        return description;
    }
    
    public void setDescription(String description) {
        this.description = description;
    }
    
    public String getImageUrl() {
        return imageUrl;
    }
    
    public void setImageUrl(String imageUrl) {
        this.imageUrl = imageUrl;
    }
    
    // ==================== 业务方法 ====================
    
    /**
     * 生成材料编码
     */
    public void generateCode() {
        if (this.code == null || this.code.isEmpty()) {
            // 格式: 分类首字母 + 年月日 + 4位随机数
            String categoryCode = this.category != null && !this.category.isEmpty() 
                ? this.category.substring(0, 1).toUpperCase() : "M";
            String date = java.time.LocalDate.now().format(java.time.format.DateTimeFormatter.ofPattern("yyyyMMdd"));
            String random = String.format("%04d", (int)(Math.random() * 10000));
            this.code = categoryCode + date + random;
        }
    }
    
    /**
     * 检查是否库存不足
     */
    public boolean isLowStock() {
        return stock.compareTo(minStock) <= 0;
    }
    
    /**
     * 检查是否即将过期(30天内)
     */
    public boolean isNearExpiry() {
        if (expiryDate == null) {
            return false;
        }
        return expiryDate.isBefore(LocalDate.now().plusDays(30));
    }
    
    /**
     * 检查是否已过期
     */
    public boolean isExpired() {
        if (expiryDate == null) {
            return false;
        }
        return expiryDate.isBefore(LocalDate.now());
    }
    
    /**
     * 入库操作
     */
    public void stockIn(BigDecimal quantity) {
        if (quantity != null && quantity.compareTo(BigDecimal.ZERO) > 0) {
            this.stock = this.stock.add(quantity);
        }
    }
    
    /**
     * 出库操作
     */
    public boolean stockOut(BigDecimal quantity) {
        if (quantity != null && quantity.compareTo(BigDecimal.ZERO) > 0 
            && this.stock.compareTo(quantity) >= 0) {
            this.stock = this.stock.subtract(quantity);
            return true;
        }
        return false;
    }
    
    /**
     * 计算库存价值
     */
    public BigDecimal getStockValue() {
        return stock.multiply(purchasePrice);
    }
    
    /**
     * 获取库存状态
     */
    public String getStockStatus() {
        if (isExpired()) {
            return "已过期";
        } else if (isNearExpiry()) {
            return "即将过期";
        } else if (isLowStock()) {
            return "库存不足";
        } else {
            return "正常";
        }
    }
}
